const { LinValidator, Rule } = require('../../core/lin-validator-v2')

const { User } = require('../models/user') //利用sequelize-User检查是否有重复数据

const { LoginType } = require('../lib/enum')

class PositiveIntegerValidator extends LinValidator {
    constructor() {
        super()  //ES6的继承机制，实质是先创造父类的实例对象this（所以必须先调用super方法），然后再用子类的构造函数修改this
        this.id = [
            new Rule('isInt', '需要正整数', { min: 1 })
        ]
    }
}
class RegisterValidator extends LinValidator {
    constructor() {
        super()
        this.email = [new Rule('isEmail', '不符合Email规范')]
        this.password1 = [
            new Rule('isLength', '密码至少6个字符,最多32个字符', { min: 6, max: 32 }),
            new Rule('matches', '密码要求为数字+英文字符+特殊字符', '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^(0-9a-zA-Z)]).{8,32}$')//正则匹配
        ]
        this.password2 = [
            new Rule('isLength', '密码至少6个字符,最多32个字符', { min: 6, max: 32 }),
            new Rule('matches', '密码要求为数字+英文字符+特殊字符', '^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^(0-9a-zA-Z)]).{8,32}$')//正则匹配
        ]
        this.nickname = [
            new Rule('isLength', '昵称不符合长度规范', { min: 4, max: 32 })
        ]
    }
    validatePassword(vals) { //自定义校验
        const psw1 = vals.body.password1 //post传参 , 参数在body
        const psw2 = vals.body.password2
        if (psw1 !== psw2) {
            throw new Error('两个密码不相同')
        }
    }
    async validateEmail(vals) { //自定义校验-查询数据库内是否有重复数据
        const email = vals.body.email
        const user = await User.findOne({ //sequelize-User模型自带查询方法=>返回的是promise这里用await转换为json对象
            where: {
                email
            }
        })
        if (user) {
            throw new Error('email已存在')
        }
    }
}

class TokenValidator extends LinValidator {
    constructor() {
        //隐藏的错误
        super()
        this.account = [
            new Rule('isLength', '不符合账号规则', {
                min: 4, max: 22
            })
        ]
        // 密码是必须要传入的吗?
        // 1.web 账号+密码
        // 2.小程序, 微信已经登录,打开小程序==合法用户==获取account即可
        // 3.手机登录 + type参数来定义
        this.secret = [
            //1.可以为空,可以不传
            //2.不能为空 不为空
            new Rule('isOptional'),//自定义方法,满足上述功能
            new Rule('isLength', '至少6个字符', {
                min: 6, max: 128
            })
        ]
    }
    //type枚举js==自定义type校验
    validateLoginType(vals) {
        if (!vals.body.type) {
            throw new Error('type是必须参数')
        }
        if (!LoginType.isThisType(vals.body.type)) {
            throw new Error('type参数不合法')
        }
    }

}

module.exports = {
    PositiveIntegerValidator,
    RegisterValidator,
    TokenValidator
}